package core.sceneManager.sceneSection.scene3DSection
{
	import core.MainManager;
	import core.sceneManager.sceneSection.SceneSection;
	
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.utils.Dictionary;
	
	import loaders.AutoRetryLoader;
	
	import memory.MemoryRecovery;
	
	import org.papervision3d.core.proto.SceneObject3D;
	import org.papervision3d.objects.DisplayObject3D;
	
	import view.ToolBitmapData;
	

	public class Pv3dShpereAddon extends SceneSection
	{
		private var loader:AutoRetryLoader;         //数据加载
		private var url:String;                     //视频的路径
		private var _waitForComplete:Boolean;       //是否等待加载完毕
		private static var movieCache:Dictionary=new Dictionary();
		private var matritx:Matrix;                 //决定视频动画的位置，大小
		private var sourceBitmap:BitmapData;        //原始的，要被视频动画代替的图片数据
		private var currentIndex:int=0;
		private var mc:MovieClip;                   //视频
		private var target:DisplayObject3D;         //所要添加动画的素材
		private var cache:Array=new Array();        //用来cache图片
		private var totalFrames:int=0;              //LOADER里面的movieclip的总帧数
		private var _waitForLoaded:Boolean;         //决定是否加载完毕才显示图片
		private var oldFrame:int=-1;                   //动画的旧帧数，如果旧帧数跟现在的帧数相等，就不更新动画了
		override public function excute(xml:XML, container:*):void
		{
			target=SceneObject3D(container).getChildByName("CustomSphere");
			initMatritx();
			this.dataBase=xml;
			for each(var item:XML in xml.attributes())
			{
				var key:String=item.name();
				try
				{
					matritx[key]=item.toString();
				}catch(e:Error){this[key]=item.toString();}
			}
		}
		//初始化矩阵，到时候可以通过XML设置矩阵里面的属性
		private function initMatritx():void
		{
			matritx=new Matrix();
			matritx.tx=100;matritx.ty=100;matritx.scale(1,1);matritx.rotate(0);
		}
		override public function start():void
		{
			if(this.url!=null && this.url!="")
			{
				loader=new AutoRetryLoader();
				loader.addEventListener(IOErrorEvent.IO_ERROR,on_error);
				loader.load(new URLRequest(this.url));
				if(_waitForLoaded)loader.contentLoaderInfo.addEventListener(Event.COMPLETE,on_loaded);//如果需要等待完毕才显示动画，那么就添加监听器
				else
				{
					MainManager.getInstance().stage.addEventListener(Event.ENTER_FRAME,updateBitmapWithoutCache);
				}
			}else
			{
				if(_waitForComplete) this.dispatchEvent(new Event(Event.COMPLETE));
			}
		}
		//更新图片，但不缓冲进内存
		private function updateBitmapWithoutCache(e:Event):void
		{
			if(loader==null
			||loader.content==null                                     //数据为空
			|| !(loader.content is MovieClip)                           //或内容不是动画 
			|| oldFrame==MovieClip(loader.content).currentFrame) return;//帧数没变化过
			getSourceBitmap();//获取原图
			target.material.bitmap.copyPixels(sourceBitmap,new Rectangle(0,0,sourceBitmap.width,sourceBitmap.height),new Point(matritx.tx,matritx.ty));//复原图片
			var bitmap:BitmapData;
			bitmap=ToolBitmapData.getInstance().drawDisplayObject(loader.content);
			if(bitmap!=null) target.material.bitmap.copyPixels(bitmap,new Rectangle(0,0,sourceBitmap.width,sourceBitmap.height),new Point(matritx.tx,matritx.ty));
		}
		//数据加载完毕，先获取原始的图片，然后再销毁LOADER
		private function on_loaded(e:Event):void
		{
			mc=MovieClip(loader.content);
			totalFrames=mc.totalFrames;
			getSourceBitmap();
			MemoryRecovery.getInstance().gcFun(loader.contentLoaderInfo,Event.COMPLETE,on_loaded);
			MemoryRecovery.getInstance().gcFun(loader,IOErrorEvent.IO_ERROR,on_error);
			loader.dispose();
			loader=null;
			MainManager.getInstance().stage.addEventListener(Event.ENTER_FRAME,updateBitmap);
			if(_waitForComplete) this.dispatchEvent(new Event(Event.COMPLETE));
		}
		//数据记载失败，如果要等待完毕，就抛出完毕的事件
		private function on_error(e:IOErrorEvent):void
		{
			if(_waitForComplete) this.dispatchEvent(new Event(Event.COMPLETE));
		}
		//获取原始的图片，材质被画上动画之后，可以用原始图片复原
		private function getSourceBitmap():void
		{
			if(sourceBitmap!=null) return;
			this.sourceBitmap=new BitmapData(loader.width*1.1,loader.height);
			sourceBitmap.copyPixels(target.material.bitmap,new Rectangle(matritx.tx,matritx.ty,loader.width*1.1,loader.height),new Point(0,0));
		}
		//更新图片,并缓冲图片进内存
		private function updateBitmap(e:Event):void
		{
			if(sourceBitmap==null)return ;
			currentIndex++;                         //每过一帧，帧数+1
			if(currentIndex>=totalFrames)currentIndex=1;//保持不越界
			target.material.bitmap.copyPixels(sourceBitmap,new Rectangle(0,0,sourceBitmap.width,sourceBitmap.height),new Point(matritx.tx,matritx.ty));//复原图片
			if(mc!=null && cache.length==totalFrames)//MC的动画全部被缓存了就停止MC
			{
				mc.stop();
				mc=null;
			}
			var bitmap:BitmapData;
			if(cache[currentIndex]==null)//如果动画当前帧，对应的图片没有CACHE，那么就先获取动画当前帧的图片，并Cache
			{
				if(mc!=null) bitmap=ToolBitmapData.getInstance().drawDisplayObject(mc);
				cache[currentIndex] = bitmap;
			}else//如果图片已经被CACHE过
			{
				bitmap=cache[currentIndex];
			}
			if(bitmap!=null) target.material.bitmap.copyPixels(bitmap,new Rectangle(0,0,sourceBitmap.width,sourceBitmap.height),new Point(matritx.tx,matritx.ty));
		}
		override public function dispose():void
		{
			super.dispose();
			if(loader!=null)MemoryRecovery.getInstance().gcFun(loader.contentLoaderInfo,Event.COMPLETE,on_loaded);
			MemoryRecovery.getInstance().gcFun(loader,IOErrorEvent.IO_ERROR,on_error);
			MemoryRecovery.getInstance().gcFun(MainManager.getInstance().stage,Event.ENTER_FRAME,updateBitmap);
			MemoryRecovery.getInstance().gcFun(MainManager.getInstance().stage,Event.ENTER_FRAME,updateBitmapWithoutCache);
			MemoryRecovery.getInstance().gcObj(loader);loader=null;
			MemoryRecovery.getInstance().gcObj(sourceBitmap);
			MemoryRecovery.getInstance().gcObj(mc);
			MemoryRecovery.getInstance().gcObj(target);target=null;
			for each(var bitmap:BitmapData in cache)
			{
				MemoryRecovery.getInstance().gcObj(bitmap);bitmap=null;
			}
			cache=null;
		}
		///////////////////////////////////////定义属性，供XML配置//////////////////////////////////
		private function set waitForComplete(val:int):void
		{
			if(val==1) _waitForComplete=true;
		}
		//设定是否需要等待完毕才显示动画。如果不设定，就是边加载边播放，而且不Cache
		private function set waitForLoaded(val:int):void
		{
			if(val==1) _waitForLoaded=true;
		}
	}
}